package ren.install.web.controller;

import cn.hutool.core.io.IoUtil;
import com.vladsch.flexmark.ast.Node;
import com.vladsch.flexmark.ext.autolink.AutolinkExtension;
import com.vladsch.flexmark.ext.emoji.EmojiExtension;
import com.vladsch.flexmark.ext.emoji.EmojiImageType;
import com.vladsch.flexmark.ext.emoji.EmojiShortcutType;
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.parser.ParserEmulationProfile;
import com.vladsch.flexmark.util.options.MutableDataSet;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import ren.install.web.bean.dto.ProjectItemDto;
import ren.install.web.common.Constants;
import ren.install.web.config.ValueCenter;
import ren.install.web.entity.DocEntity;
import ren.install.web.entity.PageInfo;
import ren.install.web.entity.PageQuery;
import ren.install.web.entity.ResultBean;
import ren.install.web.service.LuceneService;
import ren.install.web.utils.ResultUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: zhuyh
 * @date: 2018/11/21
 */
@Controller
@RequestMapping("/docs")
@Slf4j
@RequiredArgsConstructor
public class DocsController {

    private final ValueCenter valueCenter;

    private final LuceneService luceneService;


    @GetMapping("/search/{key}")
    public String search(@PathVariable("key") String key, Model model) {
        PageQuery<DocEntity> pageQuery = new PageQuery<>();
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageNum(1);
        pageInfo.setPageSize(10);
        pageQuery.setPageInfo(pageInfo);

        Map<String, String> queryMap = new HashMap<>();
        queryMap.put("key",key);
        pageQuery.setQueryParam(queryMap);

        pageQuery.setParams(new DocEntity());

        PageQuery<DocEntity> pageResult = luceneService.searchDoc(pageQuery);
        model.addAttribute("results", pageResult.getResults());
        model.addAttribute("key", key);

        return "search";
    }

    @PostMapping("/searchDoc")
    @ResponseBody
    public ResultBean<PageQuery<DocEntity>> searchDoc(@RequestBody PageQuery<DocEntity> pageQuery) {
        PageQuery<DocEntity> pageResult = luceneService.searchDoc(pageQuery);
        return ResultUtil.success(pageResult);
    }

    @GetMapping("/{project}/{version}")
    public String docs(@PathVariable String project, @PathVariable String version, Model model) throws Exception {
        model.addAttribute("title", Constants.HTML_TITLE + "|" + project);
        log.info("project:{},version:{}", project, version);

        String projectPath = valueCenter.getDocsFilePath()
                + File.separator
                + project
                + File.separator
                + version
                + File.separator;

        //获取当前项目的所有markdown文件
        List<ProjectItemDto> projectItemDtoList = new ArrayList<>();
        File[] files = cn.hutool.core.io.FileUtil.ls(projectPath);
        if (files == null) {
            model.addAttribute("projectItemDtoList", projectItemDtoList);
            return "project";
        }

        for (File file : files) {
            ProjectItemDto projectItemDto = new ProjectItemDto();
            log.info(file.getName());

            String[] fileNames = file.getName().split("\\.");
            projectItemDto.setTitle(file.getName());
            projectItemDto.setId(Integer.parseInt(fileNames[0]));

            //获取文件内容
            @Cleanup
            InputStream inputStream = new FileInputStream(projectPath + file.getName());
            String mdString = IoUtil.read(inputStream, StandardCharsets.UTF_8.name());
            mdString = mdString.replace("$staticImageURL$", "https://gitee.com/install-ren/install-ren-docs/raw/master/static/image");

            MutableDataSet options = new MutableDataSet().set(Parser.EXTENSIONS, Arrays.asList(
                    AutolinkExtension.create(),
                    EmojiExtension.create(),
                    StrikethroughExtension.create(),
                    TaskListExtension.create(),
                    TablesExtension.create()
            ))
                    // set GitHub table parsing options
                    .set(TablesExtension.WITH_CAPTION, false)
                    .set(TablesExtension.COLUMN_SPANS, false)
                    .set(TablesExtension.MIN_HEADER_ROWS, 1)
                    .set(TablesExtension.MAX_HEADER_ROWS, 1)
                    .set(TablesExtension.APPEND_MISSING_COLUMNS, true)
                    .set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
                    .set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
                    //.set(EmojiExtension.ROOT_IMAGE_PATH, emojiInstallDirectory())
                    .set(EmojiExtension.USE_SHORTCUT_TYPE, EmojiShortcutType.GITHUB)
                    .set(EmojiExtension.USE_IMAGE_TYPE, EmojiImageType.IMAGE_ONLY)
                    .set(Parser.LISTS_ORDERED_LIST_MANUAL_START, true);

            options.setFrom(ParserEmulationProfile.MARKDOWN);

            options.set(HtmlRenderer.SOFT_BREAK, "<br />\n");


            //markdown转换成html
            Parser parser = Parser.builder(options).build();
            HtmlRenderer renderer = HtmlRenderer.builder(options).build();

            // You can re-use parser and renderer instances
            Node document = parser.parse(mdString);
            String html = renderer.render(document);
            projectItemDto.setContent(html);
            projectItemDtoList.add(projectItemDto);

        }

        projectItemDtoList.sort(new Comparator<ProjectItemDto>() {
            @Override
            public int compare(ProjectItemDto o1, ProjectItemDto o2) {
                return o1.getId() - o2.getId();
            }
        });

        model.addAttribute("projectItemDtoList", projectItemDtoList);


        return "project";
    }
}
